/*******************************************************************************
 * FilePath    : /Software/Examples_Adv_MS1642/adv_app_TxRx/Src/BLE/BLE.c
 * Version     : 1.0
 * Brief       :
 * Author      : AndrewHu
 * Company     : Shanghai MacroGiga Electronics CO.,Ltd
 * Email       : Hubinbo@macrogiga.com
 * Date        : 2020-03-25 10:19:06
 * LastEditors : AndrewHu
 * LastEditTime: 2023-11-22 14:19:35
 * Description :
 ******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <Includes.h>
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define BLE_STATUS_START 0x00   // 启动
#define BLE_STATUS_RUN 0x01     // 工作
#define BLE_STATUS_STANDBY 0x02 // 休眠

#define LEN_BLE_ADDR 6
#define TXGAIN_DEF 0x12
#define LEN_DATA 31
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
// rssi(1B)+include header(2B)+mac(6B)+data(max31B), for rx application
u8 rx_buf[40] = {
    0x00,                               // rssi
    0x00,                               // adv type
    0x00,                               // data length
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mac addr
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
    0x00                                //
};

// BLE ADV_data, maxlen=31
u8 adv_data[31] = {
    // struoture 1
    // 0x02,                  //长度
    // BLE_GAP_AD_TYPE_FLAGS, //数据类型
    // 0x04,                  //数据
    // struoture 2
    0x11,                                           // 长度
    BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE,   // 数据类型,128bit UUID
    0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, // 数据
    0x00, 0x10, 0x00, 0x00, 0x24, 0x11, 0x00, 0x00, // 数据
    // struoture 3
    0x0C,                                                  // 长度
    BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME,                      // 数据类型
    'M', 'S', '1', '6', '4', '2', '-', 'A', 'D', 'V', 0x00 // 数据"MS1656"
};
u8 AdvDataLen = 31;           // 广播数据长度
u8 AdvType = ADV_NONCONN_IND; //

u8 ble_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // 蓝牙地址
u8 ble_ver;                                            //
u8 txgain_r;                                           //
u8 txgain_w;                                           //

u8 AdvChannel = 37;  // 广播通道
u8 txcnt = 0x00;     // 发送次数
u8 rxcnt = 0x00;     // 接收时间
u8 txrxdelay = 0x00; // 周期间隔
u16 ble_tick;        // 超时保护，防呆

u8 AdvDisplay = 0x01;    // 串口发送接收到的数据内容
u8 AdvChannelSet = 0x07; // 广播通道设置，bit0-37,bit1-38，bit2-39
u8 AdvTxTimes = 0x0f;    // 广播次数,每个通道广播一次算一次，建议三通道切换
u8 AdvRxTimes = 0x04;    // 接收时间,uint-50ms
u8 AdvTxRxDelay = 0x00;  // 周期间隔,uint-50ms

u8 ble_status = 0x00; // 蓝牙工作状态
/*----------------------------------------------------------------------------*/
// 时间校准
u32 WakeupCntStamp = 0, SleepCntStamp = 0;
u32 WakeupTickStamp = 0, SleepTickStamp = 0;
/* Private function ----------------------------------------------------------*/
static void BLE_Do_Cal(void);
/* extern --------------------------------------------------------------------*/
/*******************************************************************************
 * Function    : BLE_GetTick
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 11:11:25
 * Description : 获取时间
 ******************************************************************************/
void BLE_GetTick(u32 *tick)
{
    u8 temp0[6] = {0x00};

    SPI_ReadBuf(CLK_CNT, temp0, 6); //
    *tick = temp0[2];
    *tick <<= 8;
    *tick += temp0[1];
    *tick <<= 8;
    *tick += temp0[0];
}
/*******************************************************************************
 * Function    : BLE_Mode_Sleep
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 11:11:25
 * Description : BLE enter sleep mode. current: 3ua
 ******************************************************************************/
void BLE_Mode_Sleep(void)
{
    u8 temp0[4] = {0x02, 0xff, 0xff, 0xff};

    SPI_WriteBuf(SLEEP_WAKEUP | 0x20, temp0, 4);
}
/*******************************************************************************
 * Function    : BLE_Mode_Wakeup
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 11:11:48
 * Description :
 ******************************************************************************/
void BLE_Mode_Wakeup(void)
{
    SPI_WriteReg(SLEEP_WAKEUP | 0x20, 0x01);
}
/*******************************************************************************
 * Function    : BLE_Mode_PwrUp
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 11:12:02
 * Description :
 ******************************************************************************/
void BLE_Mode_PwrUp(void)
{
    SPI_WriteReg(0X50, 0x51);
    SPI_WriteReg(0X20, 0x7a); // pwr up

    SPI_WriteReg(0x50, 0x53);
    SPI_WriteReg(0X35, 0x00);
    SPI_WriteReg(0x3d, 0x1e);

    BLE_Do_Cal();
    SPI_WriteReg(0x50, 0x56);
    BLE_Mode_Sleep();
}
/*******************************************************************************
 * Function    : BLE_Mode_PwrDn
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 11:12:49
 * Description : 掉电模式，功耗最低，但是要处理好SPI的IO电平状态
 ******************************************************************************/
void BLE_Mode_PwrDn(void)
{
    u8 temp[2] = {0x81, 0x02};

    SPI_WriteReg(0X50, 0x51);
    SPI_WriteReg(0X20, 0x78); // pwr down

    SPI_WriteReg(0X50, 0x53);
    SPI_WriteReg(0x3d, 0x18);
    SPI_WriteReg(0X35, 0x01); // tm

    // temp[0] = 0x81;
    // temp[1] = 0x02;
    SPI_WriteBuf(0x13 | 0x20, temp, 2);
    SPI_WriteReg(0X3e, 0xa0);

    SPI_WriteReg(0X50, 0x56);
}
/*******************************************************************************
 * Function    : BLE_Read_RSSI
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 11:13:37
 * Description : 读取信号强度值，是一个相对值，没有校准，不是准确的强度值
 ******************************************************************************/
void BLE_Read_RSSI(unsigned char *rssi)
{
    SPI_WriteReg(0X50, 0x53);
    SPI_ReadReg(0x04, rssi);
    SPI_WriteReg(0X50, 0x56);
}
/*******************************************************************************
 * Function    : BLE_Set_StartTime
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 11:14:26
 * Description : 设置启动时间，受SPI的速度影响，详细解释见编程指南
 ******************************************************************************/
void BLE_Set_StartTime(u32 htime)
{
    u8 temp0[3];

    temp0[0] = htime & 0xFF;
    temp0[1] = (htime >> 8) & 0xFF;
    temp0[2] = (htime >> 16) & 0xFF;

    SPI_WriteBuf(START_TIME | 0x20, temp0, 3);
}
/*******************************************************************************
 * Function    : BLE_Set_TimeOut
 * Brief       :
 * Parameter   : {u32} data_us-单位时间us
 * Returns     :
 * Date        : 2020-03-25 11:15:23
 * Description : 超时时间，例如在接收时，超过设定时间没有收到广播，会产生超时中断
 ******************************************************************************/
void BLE_Set_TimeOut(u32 data_us)
{
    u8 temp0[3];

    temp0[0] = data_us & 0xff;
    temp0[1] = (data_us >> 8) & 0xff;
    temp0[2] = (data_us >> 16) & 0xff;

    SPI_WriteBuf(TIMEOUT | 0x20, temp0, 3);
}
/*******************************************************************************
 * Function    : BLE_Get_Pdu
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 11:18:13
 * Description : 接收成功时，读取广播数据内容
 ******************************************************************************/
static void BLE_Get_Pdu(u8 *ptr, u8 *len)
{
    u8 hdr_type;
    u8 len_tmp;
    u8 bank_buf[6];
    static u8 rssi = 0xff;

    BLE_Read_RSSI(ptr);
    ptr[0] = 235 - ptr[0];
    // if (ptr[0] > rssi)
    // {
    //     *len = 0;
    //     return;
    // }
    // else
    //     rssi = ptr[0];

    SPI_ReadBuf(ADV_HDR_RX, bank_buf, 2);

    *len = bank_buf[1] + 3; // 数组长度要包含RSSI,广播类型，广播数据长度
    ptr[1] = bank_buf[0];   // 读取广播类型
    ptr[2] = bank_buf[1];   // 读取广播数据长度

    hdr_type = bank_buf[0] & 0xF; // 广播类型只有低4位，参考头文件里的Pdu type定义
    len_tmp = bank_buf[1];        // 接收到的广播数据长度，包含Mac地址长度6个字节
    switch (hdr_type)
    {
    case ADV_IND:                                     // 可连接广播包
    case ADV_DIRECT_IND:                              // 可连接定向广播包
    case ADV_NONCONN_IND:                             // 不可连接广播包
    case ADV_SCAN_IND:                                // 扫描包
        SPI_ReadBuf(INITA_RX, &ptr[3], LEN_BLE_ADDR); // 获取发出广播的设备Mac地址
        len_tmp -= LEN_BLE_ADDR;
        break;
    default:
        len_tmp = 0;
        break;
    }

    if ((len_tmp > 0) && (len_tmp <= 31))
    { // 读取广播内容
        SPI_ReadBuf(R_RX_PAYLOAD, &ptr[3 + LEN_BLE_ADDR], len_tmp);
    }
    else
        *len = 0;
}
/*******************************************************************************
 * Function    : BLE_Do_Cal
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 11:18:50
 * Description : 校准函数
 ******************************************************************************/
static void BLE_Do_Cal(void) // calibration
{
    u8 data_buf[2];

    SPI_WriteReg(0x3F, 0x03);
    do
    {
        SPI_ReadReg(0x1F, &data_buf[0]);
    } while (data_buf[0] & 0x03);

    SPI_WriteReg(0x3F, 0x03);
    do
    {
        SPI_ReadReg(0x1F, &data_buf[0]);
    } while (data_buf[0] & 0x03);

    //////////////////////////////////////////////////
    SPI_WriteReg(0x35, 0x01); // testm for tx/temp
    SPI_WriteReg(0x32, 0xA0);
    SPI_WriteReg(0x2a, 0x04);
    SPI_WriteReg(0x2a, 0x00);

    SPI_WriteReg(0x32, 0x88);
    data_buf[0] = 0x01;
    data_buf[1] = 0x21;
    SPI_WriteBuf(0x13 | 0x20, data_buf, 2);
    data_buf[0] = 0x01;
    data_buf[1] = 0x20;
    SPI_WriteBuf(0x13 | 0x20, data_buf, 2);
    SPI_WriteReg(0x35, 0x00); // exist testm
    ////////////////////////////////////////////////////
}
//==============================================================================
// user code after here
//==============================================================================
/*******************************************************************************
 * Function    : BLE_SetRxDisplay
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 14:34:19
 * Description : 接收数据显示使能
 ******************************************************************************/
void BLE_SetRxDisplay(u8 enable)
{
    AdvDisplay = enable;
}
/*******************************************************************************
 * Function    : BLE_GetRxDisplay
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 17:04:19
 * Description : 获取接收数据显示使能
 ******************************************************************************/
u8 BLE_GetRxDisplay(void)
{
    return AdvDisplay;
}
/*******************************************************************************
 * Function    :
 * Brief       :
 * Parameter   : {u8} TxTimes-发送次数设定
 * Parameter   : {u8} RxTimes-接收时间设定，单位时间50ms
 * Returns     :
 * Date        : 2020-03-25 14:28:15
 * Description :
 ******************************************************************************/
void BLE_SetAdvTimes(u8 TxTimes, u8 RxTimes)
{
    AdvTxTimes = TxTimes;
    AdvRxTimes = RxTimes;
}
/*******************************************************************************
 * Function    : BLE_SetAdvData
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 11:19:51
 * Description : 设定广播包内容
 ******************************************************************************/
void BLE_SetAdvData(u8 *parameter, u8 len)
{
    memcpy(adv_data, parameter, len);
    AdvDataLen = len;

    txcnt = 0x00; // 结束当前循环，开始下一个循环，立即发送最新数据
    rxcnt = 0x00;
}
/*******************************************************************************
 * Function    : ReadFtValue
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 18:42:47
 * Description :
 ******************************************************************************/
void ReadFtValue(void)
{
    unsigned char *const ft_val = (unsigned char *)0x1FFF0E7C;

    if ((*ft_val > 11) && (*ft_val < 25))
    {
        txgain_r = *ft_val;
        txgain_w = txgain_r;
    }
    else
    {
        txgain_r = 0;
        txgain_w = TXGAIN_DEF;
    }
}
/*******************************************************************************
 * Function    : BLE_Init
 * Brief       :
 * Parameter   : {u8} power-发射功率
 * Parameter   : {u8} debug-调试模式
 * Returns     :
 * Date        : 2020-03-25 11:22:03
 * Description : 蓝牙初始化
 ******************************************************************************/
void BLE_Init(u8 power, u8 debug)
{
    u8 status;
    u8 i;
    u8 data_buf[4];

    SPI_WriteReg(0x50, 0x51);
    SPI_WriteReg(0x50, 0x53);
    SPI_WriteReg(0x35, 0x00);
    SPI_WriteReg(0x36, 0x8c); // ce=L
    SPI_WriteReg(0x3D, 0x18);
    SPI_WriteReg(0x50, 0x51);

    do
    {
        SPI_WriteReg(0x50, 0x53);

        data_buf[0] = 0;
        data_buf[1] = 0;
        data_buf[2] = 1;
        SPI_WriteBuf(0x00 | 0x20, data_buf, 3);

        SPI_WriteReg(0x36, 0x8e);
        SPI_WriteReg(0x37, 0x88);
        SPI_WriteReg(0x38, 0x88);
        SPI_WriteReg(0x39, 0x8e);

        SPI_WriteReg(0x50, 0x51);

        SPI_ReadReg(0x1e, &status);

        SPI_ReadReg(CHIP_OK, &status);
    } while (status != 0x80);

    // read chip version
    SPI_ReadReg(0x1e, &ble_ver);

    SPI_WriteReg(0X20, 0x78); // power down,tx, for hot reset
    SPI_WriteReg(0X26, 0x06); // 1Mbps
    SPI_WriteReg(0X20, 0x7a); // power up

    SPI_WriteReg(0x50, 0x56);

    BLE_Mode_Sleep();

    // read BLE address. BLE MAC Address
    status = 0x00;
    for (i = 0; i < 6; i++)
    {
        status |= ble_addr[i];
    }
    if (status != 0x00)
        SPI_WriteBuf(0x08 | 0x20, ble_addr, 6); // 如果初始化地址不为空，写入地址，掉电恢复为默认地址
    else
        SPI_ReadBuf(0x08, ble_addr, 6); // 如果为空，读取默认地址
    SPI_WriteReg(0x50, 0x53);
    if (debug)
    {
        Uart_Send_String((u8 *)"\r\nMac:", 6);
        Uart_Send_Array2Ascii_R(ble_addr, 6, 0);
    }

    data_buf[0] = 0x7f;
    data_buf[1] = 0x80; // xocc
    SPI_WriteBuf(0x14 | 0x20, data_buf, 2);

    // set BLE TX Power
    data_buf[0] = 0x02;
    data_buf[1] = power;
    SPI_WriteBuf(0x0f | 0x20, data_buf, 2);

    // SPI_ReadReg(0x08, &data_buf[1]); //txgain
    // txgain_r = data_buf[1];          //测试内容，可注释
    // if (data_buf[1] == 0x00)
    // {
    //     data_buf[1] = TXGAIN_DEF;
    // }
    // txgain_w = data_buf[1]; //测试内容，可注释
    ReadFtValue();
    if (debug)
    {
        Uart_Send_String((u8 *)"\r\nInfo:", 7);
        Uart_Send_Byte2Ascii(ble_ver);
        Uart_Send_Byte(' ');
        Uart_Send_Byte2Ascii(txgain_r);
        Uart_Send_Byte(' ');
        Uart_Send_Byte2Ascii(txgain_w);
    }
    data_buf[1] = txgain_w;
    data_buf[0] = 0xc0;
    data_buf[2] = 0x2D; // rx
    SPI_WriteBuf(0x4 | 0x20, data_buf, 3);

    data_buf[0] = 0x80; // rx
    data_buf[1] = 0x00;
    SPI_WriteBuf(0x0C | 0x20, data_buf, 2);

    data_buf[0] = 0x81;
    data_buf[1] = 0x22;
    SPI_WriteBuf(0x13 | 0x20, data_buf, 2);

    SPI_WriteReg(0X21, 0x02);
    SPI_WriteReg(0x3C, 0x30);
    SPI_WriteReg(0x3E, 0x30);

    data_buf[0] = 0x38;
    data_buf[1] = 0x0F;
    data_buf[2] = 0x00; // gc
    SPI_WriteBuf(0x02 | 0x20, data_buf, 3);

    data_buf[0] = 0x80;
    data_buf[1] = 0x70; // gain
    data_buf[2] = 0x21;
    data_buf[3] = 0x40; // rx
    SPI_WriteBuf(0x0b | 0x20, data_buf, 4);

    SPI_WriteReg(0x29, 0x71); // gain

    data_buf[0] = 0x10;
    data_buf[1] = 0x02;
    SPI_WriteBuf(0xA | 0x20, data_buf, 2);

    data_buf[0] = 0x02;
    data_buf[1] = 0x12;
    SPI_WriteBuf(0xD | 0x20, data_buf, 2);

    data_buf[0] = 0x01;
    data_buf[1] = 0x07;
    SPI_WriteBuf(0xE | 0x20, data_buf, 2);

    SPI_WriteReg(0x50, 0x56);
    SPI_WriteReg(0x20, 0x01);
}
/*******************************************************************************
 * Function    : BLE_Channel_Set
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 11:28:50
 * Description : 广播通道设置
 ******************************************************************************/
void BLE_Channel_Set(void)
{
    if (AdvChannelSet == 0x00)
        AdvChannelSet = 0x07;
    while (1)
    {
        AdvChannel++;
        if (AdvChannel == 37)
        {
            if (AdvChannelSet & 0x01)
                break;
            else
                continue;
        }
        else if (AdvChannel == 38)
        {
            if (AdvChannelSet & 0x02)
                break;
            else
                continue;
        }
        else if (AdvChannel == 39)
        {
            if (AdvChannelSet & 0x04)
                break;
            else
                continue;
        }
        else
        {
            AdvChannel = 37;
            break;
        }
    }
    SPI_WriteReg(CH_NO | 0x20, AdvChannel);
}
/*******************************************************************************
 * Function   :      RCC_AdjustHSICalibrationValue
 * Parameter  :      void
 * Returns    :      void
 * Description:
 * Note:      :      AdjustHSICalibrationValue
 *******************************************************************************/
extern unsigned long TrimValue;
void RCC_AdjustHSICalibrationValue(unsigned long ucValue)
{
    RCC->ICSCR = (RCC->ICSCR & 0xFFFF0000) | (0x4 << 13) | ucValue;
}
static void McuClockCalibration(void)
{
    u32 DeltaCnt = 0;
    u32 DeltaTick = 0;
    u32 MsCnt = 0;
    u32 Multiple = 0;

    if (GetUartStatus() == TRUE)
        return; // 有串口数据要处理，不校准时间

    // GetTimestamp(&WakeupCntStamp, &SleepCntStamp, &WakeupTickStamp, &SleepTickStamp);
    DeltaCnt = SleepCntStamp - WakeupCntStamp;
    MsCnt = DeltaCnt / 16000;

    if (WakeupTickStamp > SleepTickStamp)
        DeltaTick = MsCnt * 24000 + WakeupTickStamp - SleepTickStamp;
    else
        DeltaTick = (MsCnt + 1) * 24000 + WakeupTickStamp - SleepTickStamp;

    Multiple = DeltaTick * 100 / DeltaCnt; // x100

    if ((Multiple < 165) && (Multiple > 151)) //+1%~+10%
    {
        TrimValue -= 1;
        RCC_AdjustHSICalibrationValue(TrimValue);
    }
    else if ((Multiple < 149) && (Multiple > 135)) //-10%~-1%
    {
        TrimValue += 1;
        RCC_AdjustHSICalibrationValue(TrimValue);
    }
}
/*******************************************************************************
 * Function    : BLE_IrqInt
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 11:36:18
 * Description : BLE中断
 ******************************************************************************/
void BLE_IrqInt(void)
{
    u8 status = 0;
    u8 len_pdu = 0;
    u8 data_buf[4];
    u16 data_len = 0;

    if (IsIrqEnabled())
    {
        ble_tick = BLE_GUARD_TIME; // 防呆

        // clear interrupt flag
        SPI_ReadReg(INT_FLAG, &status);

        SPI_WriteReg(INT_FLAG | 0x20, status);
        // Uart_Send_Byte2Ascii(status); //debug

        if (INT_TYPE_WAKEUP & status)
        { // wakeup
            BLE_GetTick(&WakeupCntStamp);
            WakeupTickStamp = GetCurrentTick();

            if (txcnt > 0)
            {
                txcnt--; // 发射使能
                SPI_WriteReg(MODE_TYPE | 0x20, RADIO_MODE_ADV_TX);
                BLE_Set_StartTime(BLE_START_TIME);
                // LED_OnOff(1);
                return;
            }
            else if (rxcnt > 0)
            {
                // rxcnt --;//接收使能，计时
                SPI_WriteReg(MODE_TYPE | 0x20, RADIO_MODE_ADV_RX);
                BLE_Set_StartTime(BLE_START_TIME);
                // LED_OnOff(0);
                return;
            }
            // else
            // {
            //     BLE_Mode_Sleep(); //没有发射也没有接收，进入休眠
            //     LED_OnOff(0);
            // }
            // return;
        }

        BLE_Mode_Sleep();

        if (INT_TYPE_PDU_OK & status)
        { // only happen in rx application, no need porting in tx only application
            BLE_Get_Pdu(rx_buf, &len_pdu);

            if ((AdvDisplay) && (!GetUartTxFlag())) // 是否串口打印广播内容
            {
                // if ((rx_buf[9] == 0x1e) && (rx_buf[10] == 0x16))
                if (len_pdu != 0x00)
                { // 数据过滤
                    Uart_Send_String((u8 *)"\r\nCH:", 5);
                    AHL_Data_Hex2DecAscii_8bit(AdvChannel, data_buf, &data_len); // ASCII输出
                    Uart_Send_String(data_buf, data_len);                        // 十进制显示广播通道
                    Uart_Send_String((u8 *)" RX:", 4);
                    Uart_Send_Array2Ascii(rx_buf, len_pdu, 1);
                }
            }
        }
        else if (INT_TYPE_TX_START & status)
        { // only happen in tx application
          // Uart_Send_String((u8*)"TX:Success!!!\r\n", 15);
        }

        if (INT_TYPE_SLEEP & status)
        { // sleep
            BLE_GetTick(&SleepCntStamp);
            SleepTickStamp = GetCurrentTick();
            McuClockCalibration();

            BLE_Channel_Set(); // 切换通道
            if ((txcnt | rxcnt) == 0)
            {
                ble_status = BLE_STATUS_STANDBY;
                BLE_Mode_PwrDn(); // 发送和接收任务都完成了，进入掉电模式
                return;
            }
            else
            {
                BLE_Mode_Wakeup(); // 唤醒继续发送或接收
            }
        }
    }
}
/*******************************************************************************
 * Function    : BLE_Start
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 14:25:34
 * Description : 蓝牙使能判断
 ******************************************************************************/
void BLE_Start(void)
{
    u8 data_buf[2];

    ble_tick = BLE_GUARD_TIME;
    txcnt = AdvTxTimes;
    rxcnt = AdvRxTimes;
    txrxdelay = 0x00;

    BLE_Mode_PwrUp();

    // set BLE TX default channel:37.38.39
    SPI_WriteReg(CH_NO | 0x20, AdvChannel);
    // BLT FIFO write adv_data . max len:31 byte
    SPI_WriteBuf(W_TX_PAYLOAD | 0x20, adv_data, AdvDataLen);

    // PDU TYPE: 2  non-connectable undirected advertising . tx add:random address
    // set BLT PDU length:adv_data+6 mac adress.
    data_buf[0] = AdvType | 0x00; // bit7-公共地址或随机地址
    data_buf[1] = AdvDataLen + LEN_BLE_ADDR;
    SPI_WriteBuf(ADV_HDR_TX | 0x20, data_buf, 2);

    // clear all interrupt
    data_buf[0] = 0xff;
    data_buf[1] = 0x80;
    SPI_WriteBuf(INT_FLAG | 0x20, data_buf, 2);

    BLE_Set_TimeOut(BLE_RX_TIMEOUT);

    BLE_Mode_Wakeup();
}
/*******************************************************************************
 * Function    :
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 14:24:16
 * Description : 广播运行
 ******************************************************************************/
void BLE_TRX(void)
{
    u8 i;
    static u8 unit_delay = 0;

    i = (u8)GetSysTickCount();
    i = i - unit_delay;
    if (i >= 50)
    { // 50ms
        unit_delay = (u8)GetSysTickCount();
    }
    else
        i = 0x00;

    switch (ble_status)
    {
    case BLE_STATUS_START: // 启动
        BLE_Start();
        ble_status = BLE_STATUS_RUN; // 进入收发状态
        break;
    case BLE_STATUS_RUN: // 执行收发
    {
        BLE_IrqInt();
        if (i != 0)
        { // 50ms
            if (ble_tick)
                ble_tick--;
            else
            { // 重新启动
                // BLE_Mode_Sleep();
                BLE_Init(BLE_TX_POWER0dbm, 0);
                ble_status = BLE_STATUS_START;
            }

            if ((txcnt == 0) && (rxcnt != 0))
                rxcnt--; // 接收时间-50ms
        }
        break;
    }
    default: // BLE_STATUS_STANDBY:
    {
        // 休眠状态，一个收发周期完成，计算收发间隔
        if ((AdvTxTimes | AdvRxTimes) != 0)
        { // 有收发
            if (i != 0x00)
            { // 50ms
                // 收发周期间隔
                txrxdelay++;
                if (txrxdelay >= AdvTxRxDelay)
                { //
                    // txrxdelay=0x00;
                    ble_status = BLE_STATUS_START;
                }
            }
        }
        break;
    }
    }
}
/*******************************************************************************
 * Function    : BLE_Work_Status
 * Brief       : 工作状态
 * param        {u8} txTimes-发射次数
 * param        {u8} rxTime-接收时间(unit-50ms)
 * return       {*}
 * Description :
 * Date        : 2021-06-08 10:07:38
 ******************************************************************************/
void BLE_Work_Status(u8 txTimes, u8 rxTime)
{
    AdvTxTimes = txTimes;
    AdvRxTimes = rxTime;
}
